package com.xbstar.wei.service2;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.http.Consts;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.entity.mime.HttpMultipartMode;
import org.apache.http.entity.mime.MultipartEntityBuilder;

import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;
import org.json.JSONException;
import org.json.JSONObject;



import com.xbstar.wei.service2.Message.EventType;
import com.xbstar.wei.service2.Message.MsgContent;
import com.xbstar.wei.service2.Message.MsgType;

/**
 * 微信服务类
 * 
 * @author jwf
 * @version 2.0 默认编码UTF8
 * 2015/12/22
 * 删除与其他包相关的类引用，用于保持本框架的独立性
 */
public abstract class JFWeiService extends HttpServlet {

	private HashMap<String, Object> resMap;
	private HashMap<String, Object> _map;
	private HttpServletRequest _request;

	protected HttpServletRequest getRequest() {
		if (_request == null) {
			return null;
		}
		return _request;
	}

	protected void setRequest(HttpServletRequest request) {
		this._request = request;
	}

	@Override
	protected void doPost(HttpServletRequest request, HttpServletResponse resp)
			throws ServletException, IOException {
		System.out.println("进入post");
		//resp.setContentType("");
		//resp.setHeader("Content-type","charat=utf8");
		//resp.setHeader(arg0, arg1)
		//resp.setContentType("text/html;charset=UTF-8");
		 resp.setCharacterEncoding("UTF-8");
		if (!WeixinUtil.checkWeixinReques(request)) {
			return;
		}
		HashMap<String, Object> map = (HashMap<String, Object>) WeixinUtil.xml2Map
				.getAWeiMapByRequest(request);
		if (map == null) {// 如果没有传入数据则此次会话无效
			return;
		}
		_map = map;
		System.out.println("这次获得的map是"+map.toString());

		if (map.get(Message.MsgContent.MsgType).equals(MsgType.Event)) {// 判断是否为事件消息
			if (map.get(MsgContent.Event).equals(EventType.Click)) {// 判断是否为点击事件
				HashMap<String, String> evmap = new HashMap<String, String>();
				evmap.put(MsgContent.FromUserName,
						"" + map.get(MsgContent.FromUserName));
				evmap.put(MsgContent.EventKey,
						"" + map.get(MsgContent.EventKey));
				evmap.put(MsgContent.CreateTime,
						"" + map.get(MsgContent.CreateTime));
				this.onWeiClick(evmap);
			} else if (map.get(MsgContent.Event).equals(EventType.Location)) {// 判断是否为上传地理信息
				HashMap<String, String> evmap = new HashMap<String, String>();
				evmap.put(MsgContent.FromUserName,
						"" + map.get(MsgContent.FromUserName));
				evmap.put(MsgContent.Latitude,
						"" + map.get(MsgContent.Latitude));
				evmap.put(MsgContent.Longitude,
						"" + map.get(MsgContent.Longitude));
				evmap.put(MsgContent.CreateTime,
						"" + map.get(MsgContent.CreateTime));
				this.onWeiLocation(evmap);
			} else if (map.get(MsgContent.Event).equals(EventType.Subscribe)) {// 用户关注事件
				HashMap<String, String> evmap = new HashMap<String, String>();
				evmap.put(MsgContent.FromUserName,
						"" + map.get(MsgContent.FromUserName));
				evmap.put(MsgContent.CreateTime,
						"" + map.get(MsgContent.CreateTime));
				this.onWeiSubscribe(evmap);

			} else if (map.get(MsgContent.Event).equals(EventType.Unsubscribe)) {// 用户取消关注事件
				HashMap<String, String> evmap = new HashMap<String, String>();
				evmap.put(MsgContent.FromUserName,
						"" + map.get(MsgContent.FromUserName));
				evmap.put(MsgContent.CreateTime,
						"" + map.get(MsgContent.CreateTime));
				this.onWeiUnSubscribe(evmap);
			} else {
				resMap = WeixinUtil.produceTextMessege(map, "此功能未被开发");
			}

		}
		/**
		 * 用户收到文本消息
		 */
		else if (map.get(Message.MsgContent.MsgType).equals(MsgType.Text)) {
			HashMap<String, String> evmap = new HashMap<String, String>();
			evmap.put(MsgContent.FromUserName,
					"" + map.get(MsgContent.FromUserName));
			evmap.put(MsgContent.CreateTime,
					"" + map.get(MsgContent.CreateTime));
			evmap.put(MsgContent.Content, "" + map.get(MsgContent.Content));
			this.onWeiText(evmap);
		} else {
			resMap = WeixinUtil.produceTextMessege(map, "此功能未被开发");
		}

		if (resMap != null) {
			String spri = WeixinUtil.getAWeiXmlByMapString(resMap);
			resp.getWriter().write(spri);
		} else {
			resp.getWriter().write("");
		}

	}

	/**
	 * 用户发来文本消息
	 * 
	 * @param evmap
	 *            <MsgContent.FromUserName,MsgContent.CreateTime,MsgContent.
	 *            Content>
	 */
	protected abstract void onWeiText(HashMap<String, String> evmap);

	/**
	 * 用户取消关注事件
	 * 
	 * @param evmap
	 *            <MsgContent.FromUserName,MsgContent.CreateTime>
	 */
	protected abstract void onWeiUnSubscribe(HashMap<String, String> evmap);

	/**
	 * 用户关注事件
	 * 
	 * @param evmap
	 *            <MsgContent.FromUserName,MsgContent.CreateTime>
	 */
	protected abstract void onWeiSubscribe(HashMap<String, String> evmap);

	/**
	 * 用户上传地理位置信息事件
	 * 
	 * @param evmap
	 *            <MsgContent.FromUserName,MsgContent.Latitude,MsgContent.
	 *            Longitude,MsgContent.CreateTime>
	 */
	protected abstract void onWeiLocation(HashMap<String, String> evmap);

	/**
	 * 产生了一个微信click事件
	 * 
	 * @param evmap
	 *            <MsgContent.FromUserName,MsgContent.EventKey,MsgContent.
	 *            CreateTime>
	 */
	protected abstract void onWeiClick(HashMap<String, String> evmap);

	@Override
	protected void doGet(HttpServletRequest request, HttpServletResponse resp)
			throws ServletException, IOException {
		String echostr = request.getParameter("echostr");
		System.out.println("echostr=" + echostr);
		if (WeixinUtil.checkWeixinReques(request) && echostr != null) {
			resp.getWriter().write(echostr);
		} else {
			resp.getWriter().write("error");
		}
	}

	/**
	 * 
	 * @param strText
	 *            要发送的文本串
	 * 
	 */
	protected void produceTextMessage(String strText) {
		if (_map == null) {
			return;
		}
		resMap = WeixinUtil.produceTextMessege(_map, strText);
	}

	/**
	 * 产生一个图文消息
	 * 
	 * @param Articles
	 */
	protected void produceNewsMessage(
			ArrayList<HashMap<String, String>> Articles) {
		if (_map == null) {
			return;
		}
		resMap = WeixinUtil.produceNewsMessege(_map, Articles);
	}

	/**
	 * 
	 * @param Description
	 *            图片描述
	 * @param Title
	 *            图片标题
	 * @param PicUrl图片来源链接
	 * @param Url
	 *            图片指向链接
	 * @return
	 */
	public static HashMap<String, String> itemFormatOfNews(String Description,
			String Title, String PicUrl, String Url) {
		return WeixinUtil.itemFormatOfNews(Description, Title, PicUrl, Url);
	}

	/**
	 * 用于需要保存用户认证信息的操作，需要在需要认证的jsp中执行此代码
	 * 
	 * @param request
	 *            jsp中的reuqes
	 * @return 返回的是一些添加信息，如果为空串，则表示成功
	 */
	public static String setSessionFromPageRequest(HttpServletRequest request,
			HttpSession session) {
		WeixinUtil weiUtil = new WeixinUtil();
		weiUtil.setNeedAuthorReuqest(request, session);
		System.out.println(session.getAttribute("code"));
		System.out.println("设置code到session中");
		if (!weiUtil.isAuthored()) {
			return weiUtil.getResultString();
		}
		return "";

	}

	/**
	 * 从request获取opendid，这种方法用于页面授权认证
	 * 
	 * @param request
	 * @return 若不成功则返回null,不成功原因可能是用户没有授权
	 */
	public static String getOpenIdFromRequest(HttpServletRequest req) {

		HttpSession session = req.getSession(false);
		if (session == null) {
			return null;
		}
		// System.out.println(session.get);
		String openId = (String) session.getAttribute("openid");
		if (openId != null && !"".equals(openId)) {
			return openId;
		}
		System.out.println("此处是在获取code值时的code：" + session.getAttribute("code"));
		String code = (String) session.getAttribute("code");
		if ("123".equals(code)) {
			return "123";
		}
		boolean isAuthor = false;

		if (code == null || "".equals(code)) {
			return null;
		}
		openId = UserUtil.getOpenIdByAuthorCode(code);

		if (openId == null || "".equals(openId)) {
			return null;
		} else {
			System.out.println("openid的值是："+openId);
			session.setAttribute("openid", openId);

//			if (JFWeiService.getLoginFlagByOpenId(openId)) {
//				com.xbstar.wei.model.UserUtil us = new com.xbstar.wei.model.UserUtil();
//				String uname = us.getUserNameByWX(openId);
//				setUserNameToRequestSession(req, uname);
//			}
			return openId;
		}
	}

	/**
	 * 设置session存储用户名
	 * 
	 * @param req
	 * @param uname
	 */
	public static void setUserNameToRequestSession(HttpServletRequest req,
			String uname) {
		if (uname == null || req == null) {
			return;
		}
		HttpSession sess = req.getSession(true);
		sess.setAttribute("name", uname);

	}

	/**
	 * 从request中获取用户名称
	 * 
	 * @param req
	 * @return空值返回null
	 */

	public static String getUserNameFromReuqest(HttpServletRequest req) {
		if (req == null) {
			return null;

		}
		HttpSession sess = req.getSession(false);
		try {
			if (!sess.getAttribute("name").equals("")) {
				return (String) sess.getAttribute("name");
			}
		} catch (Exception e) {
			return null;

		}
		return null;

	}

	/**
	 * 把页面session存入，参考带session传值
	 * 
	 * @param request
	 * @return
	 */
	public static String setSessionFromPageRequest(HttpServletRequest request) {

		WeixinUtil weiUtil = new WeixinUtil();
		weiUtil.setNeedAuthorReuqest(request);
		System.out.println("保存session完成");
		if (!weiUtil.isAuthored()) {
			return weiUtil.getResultString();
		}
		return "";

	}
	public static JSONObject upLoadTmpMedia(String type,File upfile,String fileName) throws Exception{
		if (!upfile.exists()) {
			return null;
		}
		
		String weiUrl=WeiURL.getAddMediaByType(type);
		HttpClient client=SSLUtils.createHttpsClient();
		HttpPost post=new HttpPost(weiUrl);
		try {
			MultipartEntityBuilder postBuilder=MultipartEntityBuilder.create();
			postBuilder.setMode(HttpMultipartMode.STRICT);
			postBuilder.addBinaryBody("media", upfile, ContentType.create("application/octet-stream", Consts.UTF_8), fileName);
			//FileEntity fileEntity=new FileEntity(upfile);
			//post.setHeader( "form-data","name=\"media\";filelength=\"{"+upfile.length()+"}\";filename=\"{"+fileName+"}\"\r\nContent-Type:application/octet-stream\r\n\r\n");
			post.setEntity(postBuilder.build());
		} catch (Exception e) {
			System.out.println("创建文件流出错");
			throw e;
		}
		
		HttpResponse response;
		try {
			 response =client.execute(post);
		} catch (Exception e) {
			Exception ee=new Exception("未能成功上传，可能网络问题，请检查网络后再次尝试！");
			throw ee;
		}
		if(response.getStatusLine().getStatusCode()!=HttpStatus.SC_OK ) {
			Exception ee=new Exception("网络配置头部有错，请检查确认");
			throw ee;
		}
		String str=EntityUtils.toString(response.getEntity());
		JSONObject object;
		try {
			object = new JSONObject(str);
		} catch (Exception e) {
			Exception ee=new Exception("获取的流转化为json失败");
			throw ee;
		}
		int numF=-1;
		try {
			numF=object.getInt("errcode");
		} catch (Exception e) {
			System.out.println("没有errcode这个字段");
			try {
				String errStr=(String)object.get("errmsg");
				if (errStr!=null||!errStr.equals("")) {
					System.out.println("错误数据，没有errcode字段,却有errmsg字段");
					throw e;
				}
			} catch (Exception e2) {
				return object;
			}
		}
		if (numF!=0) {
			client.getConnectionManager().shutdown();	
			throw new Exception("错误编码： "+object.getInt("errcode")+" 错误参考信息： "+object.getString("errmsg"));
		}else {
			return object;
		}
	}
	
	/**
	 * 采用post向微信服务器发送jsonobject对象的方法
	 * @param url 微信连接地址
	 * @obj obj 要发送的对象
	 * @return 返回从服务器中获得值
	 * @throws Exception 
	 */
	public static JSONObject send2WeiByPostMethod(String url,JSONObject obj) throws Exception {
		if (obj==null||url==null) {
			return null;
		}
		HttpClient client=new DefaultHttpClient();
		HttpPost post=new HttpPost(url);
		StringEntity json=new StringEntity(obj.toString(),"UTF-8");
		post.setEntity(json);
		HttpResponse response;
		try {
			 response =client.execute(post);
		} catch (Exception e) {
			Exception ee=new Exception("未能成功上传，可能网络问题，请检查网络后再次尝试！");
			throw ee;
		}
		if(response.getStatusLine().getStatusCode()!=HttpStatus.SC_OK ) {
			Exception ee=new Exception("网络配置头部有错，请检查确认");
			throw ee;
		}
		String str=EntityUtils.toString(response.getEntity());
		JSONObject object;
		try {
			object = new JSONObject(str);
		} catch (Exception e) {
			Exception ee=new Exception("获取的流转化为json失败");
			throw ee;
		}
		int numF=-1;
		try {
			numF=object.getInt("errcode");
		} catch (Exception e) {
			System.out.println("没有errcode这个字段");
			return object;
		}
		if (numF!=0) {
			if (numF!=-1) {
				client.getConnectionManager().shutdown();	
				throw new Exception("错误编码： "+object.getInt("errcode")+" 错误参考信息： "+object.getString("errmsg"));
			}else {
				return object;
			}
			
		}else {
			return object;
		}
		
	}
	
}
